package com.study.talk.data.net

import android.app.Application
import android.content.Context
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.study.talk.data.model.GroupInfo
import com.study.talk.data.model.MomentComment
import com.study.talk.data.model.MomentLike
import com.study.talk.data.model.User
import com.study.talk.data.model.UserInfo
import com.study.talk.data.model.resp.FriendUserInfoListResponse
import com.study.talk.data.model.resp.GroupInfoResponse
import com.study.talk.data.model.resp.MomentResponse
import com.study.talk.data.model.resp.QueryUserListResponse
import com.study.talk.data.model.resp.ResultResponse
import com.study.talk.data.model.resp.UploadFileResponse
import com.study.talk.data.model.resp.UserInfoResponse
import com.study.talk.data.model.vo.GroupUserInfoVo
import com.study.talk.data.model.vo.MomentCommentVo
import com.study.talk.data.model.vo.MomentLikeVo
import com.study.talk.data.model.vo.MomentVo
import com.study.talk.data.net.OkHttp.delete
import com.study.talk.data.net.OkHttp.get
import com.study.talk.data.net.OkHttp.post
import com.study.talk.data.net.OkHttp.postFile
import com.study.talk.data.net.OkHttp.uploadFiles
import com.study.common.GSONUtil
import com.study.common.annotation.Desc
import com.study.talk.data.model.GroupUserInfo
import com.study.talk.data.model.Message
import com.study.talk.data.model.resp.BoolResponse
import com.study.talk.data.model.resp.GroupUserInfoResponse
import com.study.talk.data.model.resp.MessageTypeResponse
import com.study.talk.data.model.resp.QueryGroupInfoListResponse
import com.study.talk.data.model.resp.RegisterHttpResponse
import com.study.talk.data.model.vo.RegisterUserVo
import com.study.talk.data.model.vo.UserInfoVo
import com.study.talk.data.net.OkHttp.put
import top.zibin.luban.Luban
import top.zibin.luban.OnCompressListener
import java.io.File


@Deprecated("全面转向MVVM架构,网络请求曾在remote和repository")
object NetApi {
    fun getUserInfo(
        userId: Int, success: (UserInfo) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/userInfo/get/$userId", error = fail, success = { res: String ->
            val response = GSONUtil.fromJson(
                res, UserInfoResponse::class.java
            )
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })

    }

    fun getGroupInfo(
        groupId: Int, success: (GroupInfo) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/groupInfo/$groupId", error = fail, success = { res: String ->
            val response = GSONUtil.fromJson(
                res, GroupInfoResponse::class.java
            )
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    fun uploadMultipleFileCompress(
        files: List<String>,
        context: Application,
        success: (ArrayList<String>) -> Unit,
        fail: (String) -> Unit
    ) {

        val fileList = Luban.with(context).load(files).get()
        val resultsList: MutableList<String> = ArrayList()
        for (file in fileList) {
            resultsList.add(file.path)
        }
        uploadFiles(url = "/file/upload/image/multiple/other",
            paths = resultsList,
            error = fail,
            success = { res: String ->
                val type = object : TypeToken<ResultResponse<List<String>>>() {}.type
                val response = GSONUtil.fromJson<ResultResponse<ArrayList<String>>>(
                    res, type
                )
                if (response.status == 200) {
                    success.invoke(response.data)
                } else {
                    fail.invoke(response.message)
                }
            })

    }

    fun uploadMultipleFile(
        files: List<String>, success: (ArrayList<String>) -> Unit, fail: (String) -> Unit
    ) {
        uploadFiles(url = "/file/upload/image/multiple",
            paths = files,
            error = fail,
            success = { res: String ->
                val type = object : TypeToken<ResultResponse<List<String>>>() {}.type
                val response = GSONUtil.fromJson<ResultResponse<ArrayList<String>>>(
                    res, type
                )
                if (response.status == 200) {
                    success.invoke(response.data)
                } else {
                    fail.invoke(response.message)
                }
            })
    }

    fun addMoment(
        userInfo: UserInfo,
        photos: ArrayList<String>,
        content: String,
        success: (Boolean) -> Unit,
        fail: (String) -> Unit
    ) {
        val momentVo = MomentVo(
            userInfo.id, userInfo.avatar, userInfo.username, photos, content
        )
        post(url = "/moment/add",
            gson = GSONUtil.toJson(momentVo),
            error = fail,
            success = { res: String ->
                val response = GSONUtil.fromJson<ResultResponse<Any>>(
                    res, object : TypeToken<ResultResponse<Any>>() {}.type
                )
                if (response.status == 200) {
                    success.invoke(true)
                } else {
                    fail.invoke(response.message)
                }
            })
    }

    fun getUserMomentList(
        userId: Int, success: (List<MomentResponse>) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/moment/get/my/moment/$userId", error = fail, success = { res: String ->
            val response = GSONUtil.fromJson<ResultResponse<List<MomentResponse>>>(
                res, object : TypeToken<ResultResponse<List<MomentResponse>>>() {}.type
            )
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    @Desc("根据userId获取朋友圈列表")
    fun getFriendMomentList(
        userId: Int, success: (List<MomentResponse>) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/moment/get/friend/moment/$userId", error = fail, success = { res: String ->
            val response = GSONUtil.fromJson<ResultResponse<List<MomentResponse>>>(
                res, object : TypeToken<ResultResponse<List<MomentResponse>>>() {}.type
            )
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }


    fun updateMomentLike(
        user: User, momentId: Int, likeState: Int, success: (Int) -> Unit, fail: (String) -> Unit
    ) {
        val momentLikeVo = MomentLikeVo(
            momentId, user.id, user.username, likeState
        )
        post(url = "/moment_like/add",
            gson = GSONUtil.toJson(momentLikeVo),
            error = fail,
            success = { res: String ->
                val response = GSONUtil.fromJson<ResultResponse<Int>>(
                    res, object : TypeToken<ResultResponse<Int>>() {}.type
                )
                if (response.status == 200) {
                    success.invoke(response.data)
                } else {
                    fail.invoke(response.message)
                }
            })
    }

    /** 朋友圈评论 */
    fun addMomentComment(
        user: User,
        momentId: Int,
        content: String,
        success: (List<MomentComment>) -> Unit,
        fail: (String) -> Unit
    ) {
        val momentCommentVo = MomentCommentVo(
            momentId, user.id, user.username, content
        )
        post(url = "/moment_comment/add",
            gson = GSONUtil.toJson(momentCommentVo),
            error = fail,
            success = { res: String ->

                val response = GSONUtil.fromJson<ResultResponse<List<MomentComment>>>(
                    res, object : TypeToken<ResultResponse<List<MomentComment>>>() {}.type
                )
                if (response.status == 200) {
                    success.invoke(response.data)
                } else {
                    fail.invoke(response.message)
                }
            })
    }

    /** 删除朋友权评论 */
    fun deleteMomentComment(
        momentComment: MomentComment, success: (List<MomentComment>) -> Unit, fail: (String) -> Unit
    ) {
        delete(url = "/moment_comment/delete",
            gson = GSONUtil.toJson(momentComment),
            error = fail,
            success = { res: String ->
                val response = GSONUtil.fromJson<ResultResponse<List<MomentComment>>>(
                    res, object : TypeToken<ResultResponse<List<MomentComment>>>() {}.type
                )
                if (response.status == 200) {
                    success.invoke(response.data)
                } else {
                    fail.invoke(response.message)
                }
            })
    }

    /** 获取朋友圈的点赞列表 */
    fun getLikeList(
        momentId: Int, success: (List<MomentLike>) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/moment_like/get/list/$momentId", error = fail, success = { res: String ->
            val response = GSONUtil.fromJson<ResultResponse<List<MomentLike>>>(
                res, object : TypeToken<ResultResponse<List<MomentLike>>>() {}.type
            )
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 上传图片，会先压缩 */
    fun uploadImage(
        path: String, context: Context, success: (String) -> Unit, fail: (String) -> Unit
    ) {
        Luban.with(context).load(path).setCompressListener(object : OnCompressListener {
            override fun onStart() {
            }

            override fun onSuccess(file: File) {
                postFile(url = "/file/register/upload/image",
                    path = file.path,
                    error = fail,
                    success = { res: String ->
                        val response = GSONUtil.fromJson(
                            res, UploadFileResponse::class.java
                        )
                        if (response.status == 200) {
                            success.invoke(response.data)
                        } else {
                            fail.invoke(response.message)
                        }
                    })
            }

            override fun onError(e: Throwable) {
            }
        }).launch()
    }

    /** 删除好友 */
    fun deleteFriend(friendId: Int, success: (Boolean) -> Unit, fail: (String) -> Unit) {
        delete(url = "/friend/delete/${friendId}", error = fail, success = {
            val response: ResultResponse<Boolean> =
                GSONUtil.fromJson(it, object : TypeToken<ResultResponse<Boolean>>() {}.type)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 退出群聊 */
    fun exitGroup(groupId: Int, success: (Boolean) -> Unit, fail: (String) -> Unit) {
        delete(url = "/groupUserInfo/exit/${groupId}", error = fail, success = {
            val response: ResultResponse<Boolean> =
                GSONUtil.fromJson(it, object : TypeToken<ResultResponse<Boolean>>() {}.type)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 查询还未在群中的好友 */
    fun friendNotInGroup(
        groupId: Int, userId: Int, success: (List<UserInfo>) -> Unit, fail: (String) -> Unit
    ) {
        post(url = "/friend/get/not/in/group/list", gson = GSONUtil.toJson(
            GroupUserInfoVo(
                groupId, userId
            )
        ), error = fail, success = { res: String ->
            val response = GSONUtil.fromJson(res, QueryUserListResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 查询是否为自己好友 */
    fun friend(userId: Int, success: (Boolean) -> Unit, fail: (String) -> Unit) {
        get(url = "/friend/isFriend/${userId}", error = fail, success = {
            val response: ResultResponse<Boolean> =
                GSONUtil.fromJson(it, object : TypeToken<ResultResponse<Boolean>>() {}.type)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 获取好友信息列表 */
    fun getFriendInfos(success: (List<UserInfo>) -> Unit, fail: (String) -> Unit) {
        get(url = "/friend/userInfoList", error = fail, success = { res: String ->
            val response: FriendUserInfoListResponse =
                GSONUtil.fromJson(res, FriendUserInfoListResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 获取群聊信息列表 */
    fun getGroupInfos(success: (List<GroupInfo>) -> Unit, fail: (String) -> Unit) {
        get(url = "/groupInfo/get/group/list/user/id", error = fail, success = { res: String ->
            val response = Gson().fromJson<ResultResponse<List<GroupInfo>>>(
                res, object : TypeToken<ResultResponse<List<GroupInfo>>>() {}.type
            )
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 更新用户信息 */
    fun updateUserInfo(userInfo: UserInfo, success: (String) -> Unit, fail: (String) -> Unit) {
        put(url = "/userInfo/update",
            gson = GSONUtil.toJson(userInfo),
            error = fail,
            success = { res: String ->
                val response = GSONUtil.fromJson(res, RegisterHttpResponse::class.java)
                if (response.status == 200) {
                    success.invoke(response.data)
                } else {
                    fail.invoke(response.message)
                }
            })
    }

    /** 查询用户是否在群聊中 */
    fun inGroup(groupId: Int, userId: Int, success: (Boolean) -> Unit, fail: (String) -> Unit) {
        post(url = "/groupUserInfo/query/has/member", gson = GSONUtil.toJson(
            GroupUserInfoVo(
                groupId, userId
            )
        ), error = fail, success = { res: String ->
            val response = GSONUtil.fromJson(res, BoolResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 获取群聊成员 */
    fun getGroupMembers(
        groupId: Int, success: (List<GroupUserInfo>) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/groupUserInfo/get/user/list/$groupId", error = fail, success = { res ->
            val response = GSONUtil.fromJson(res, GroupUserInfoResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 根据关键字搜索好友 */
    fun queryUserInfosByKeyword(
        keyword: String, success: (List<UserInfo>) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/userInfo/get/list/$keyword", error = fail, success = {
            val response = GSONUtil.fromJson(it, QueryUserListResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 根据群聊名称搜索群聊 */
    fun queryGroupInfosByKeyword(
        keyword: String, success: (List<GroupInfo>) -> Unit, fail: (String) -> Unit
    ) {
        get(url = "/groupInfo/get/list/$keyword", error = fail, success = {
            val response = GSONUtil.fromJson(it, QueryGroupInfoListResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 注册账号 */
    fun registerAccount(user: UserInfoVo, success: (String) -> Unit, fail: (String) -> Unit) {
        post(url = "/user/register", gson = GSONUtil.toJson(user), error = fail, success = {
            val response = GSONUtil.fromJson(it, RegisterHttpResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    /** 获取服务端返回的消息 */
    fun registerAccountSimple(
        registerUserVo: RegisterUserVo, success: (User) -> Unit, fail: (String) -> Unit
    ) {
        post(url = "/user/register/simple",
            gson = GSONUtil.toJson(registerUserVo),
            error = fail,
            success = {
                val response = GSONUtil.fromJson<ResultResponse<User>>(
                    it, object : TypeToken<ResultResponse<User>>() {}.type
                )
                if (response.status == 200) {
                    success.invoke(response.data)
                } else {
                    fail.invoke(response.message)
                }
            })
    }

    /** 获取缓存消息 */
    fun getCacheMsg(userId: Int, success: (List<Message>) -> Unit, fail: (String) -> Unit) {
        get(url = "/message/list/$userId", error = fail, success = {
            val response = GSONUtil.fromJson(it, MessageTypeResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }

    fun disbandGroup(groupId: Int, success: (Boolean) -> Unit, fail: (String) -> Unit) {
        get(url = "/groupInfo/update/disband/$groupId", error = fail, success = {
            val response = GSONUtil.fromJson(it, BoolResponse::class.java)
            if (response.status == 200) {
                success.invoke(response.data)
            } else {
                fail.invoke(response.message)
            }
        })
    }
}